package com.fagp.mew.cms.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fagp.mew.cms.messages.PageRequest;
import com.fagp.mew.cms.messages.PageResponse;
import com.fagp.mew.cms.service.ILogService;
import com.fagp.mew.cms.utils.UpDownloadUtil;
import com.mew.common.config.RedisConstantValue;
import com.mew.common.dc.db.ProfileService;
import com.mew.common.dc.mapper.ProfileMapper;
import com.mew.common.dc.mapper.UserMapper;
import com.mew.common.dc.redis.UserProfileRedisService;
import com.mew.common.entity.user.Profile;
import com.mew.common.entity.user.User;
import com.mew.common.util.MD5Encrypt;
import com.mew.common.util.NumberUtil;
import com.mew.common.util.RandomIdUtil;
import com.mew.common.util.StringUtils;
import com.mew.common.vo.web.GoldInfoVo;
import com.mew.common.vo.web.UserDataVo;
import com.mew.common.vo.web.UserVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class UserWebService {

    @Autowired
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ProfileMapper profileMapper;
    @Autowired
    private UserProfileRedisService userProfileRedisService;
    @Autowired
    private ProfileService profileService;
    @Autowired
    private ILogService logService;


    public PageResponse getUserGold(PageRequest p, User user){

        PageResponse pageResponse = new PageResponse();
        Page<UserVo> page = PageHelper.startPage(p.getPage(), p.getLimit());

        if (org.apache.commons.lang3.StringUtils.isNotEmpty(p.field)&& org.apache.commons.lang3.StringUtils.isNotEmpty(p.order)){
            //页面点击排序
            page.setOrderBy(StringUtils.b2s(p.field)+" "+p.order);
        }else if (org.apache.commons.lang3.StringUtils.isEmpty(p.field)){
            //首次进入排序
            page.setOrderBy("add_time desc");
        }//自然排序
        String key = p.getKey();
        String value = p.getValue();
        if (org.apache.commons.lang3.StringUtils.isNotEmpty(value)){
            value = value.replace(" ","").replace("/n","");
        }

        pageResponse.data =  userMapper.getUserGold(key,value,null);
        pageResponse.count = page.getTotal();
        return pageResponse;
    }

    public PageResponse ban(User user){

        Long id = user.getId();
        Integer state = user.getState();
        if (null!=id && id>0){
            User newU = new User();
            newU.setId(id);
            String thing = "";
            if (state==0){
                newU.setState(1);
                thing = "启用用户：";
            }else {
                newU.setState(0);
                thing = "禁用用户：";
            }
            userMapper.updateById(newU);
            User byId = userMapper.selectById(user.getId());


            thing += byId.getGid();
            logService.insertLog(1,thing,user.getId());
        }

        PageResponse pageResponse = new PageResponse();
        return pageResponse;
    }

    /**
     * 生成vip
     * @param gold
     * @return
     */
    public PageResponse add(MultipartFile file, Long gold) throws Exception{
        //解析流
        InputStream inputStream = file.getInputStream();
        byte[] bytes = new byte[1024];

        int n = 0;//得到实际读取到的字节数 读到最后返回-1
        //循环读取
        StringBuilder txtStrbuilder = new StringBuilder();
        while ((n = inputStream.read(bytes)) != -1) {
            //把字节转成String 从0到N变成String
            txtStrbuilder.append(new String(bytes, 0, n));
        }

        String txtStr = txtStrbuilder.toString();
        txtStr = txtStr.replace("\r", "");
        String[] gids = txtStr.split("\n");
        if (gids.length==0){
            return new PageResponse("未检出到id");
        }

        //输出
        StringBuilder builder = new StringBuilder();
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//时间处理
        builder.append("---------------" + simpleDateFormat.format(new Date()) + "---------------" + "\n");

        for (String gid : gids) {
            if (StringUtils.isNotEmpty(gid)){
                newUser(gid,gold,builder);
            }
        }

        UpDownloadUtil.txtAdd("/web/gid.txt",builder.toString());
        return new PageResponse();
    }

    @Transactional
    public void newUser(String gid, Long gold,StringBuilder builder){
        builder.append(gid);
        String pass = UUID.randomUUID().toString().substring(0, 6);
        String md5 = MD5Encrypt.MD5(pass);
        User user = User.builder()
                .id(RandomIdUtil.getUserId())
                .gid(gid)
                .sex(2)
                .password(md5)
                .nickname(gid)
                .userType(9)
                .build();
        try {
            userMapper.insert(user);//添加
        } catch (Exception e) {
            builder.append("   id已存在\n");
            return;
        }
        Long id = user.getId();
        Profile profile = Profile.builder().userId(id).goldNumber(gold).build();
        profile.initData();
        profileMapper.insert(profile);

        builder.append("   "+pass+"\n");
    }

    public PageResponse userinfo(Long userid) throws Exception{
        if (null==userid){
            return PageResponse.builder().data(new ArrayList()).build();
        }
        User user = userProfileRedisService.getRedisUserById(userid);
        if (user==null){
            user = userMapper.selectById(userid);
        }

        Profile profile = profileService.getRedisProfileById(userid);

        Field[] fields = User.class.getDeclaredFields();

        ArrayList<HashMap<String, String>> list = new ArrayList<>();
        for (Field field : fields) {
            HashMap<String, String> map = new HashMap<>();

            if ("gid".equals(field.getName())){
                map.put("key","id");
            }else if ("accountNumber".equals(field.getName())){
                map.put("key","账号");
            }else if ("telNumber".equals(field.getName())){
                map.put("key","手机号");
            }else if ("nickname".equals(field.getName())){
                map.put("key","昵称");
            }else if ("userType".equals(field.getName())){
                map.put("key","类型");
            }else if ("addMac".equals(field.getName())){
                map.put("key","注册mac");
            }else if ("addIp".equals(field.getName())){
                map.put("key","注册ip");
            }else if ("password".equals(field.getName())){
                map.put("key","密码");
            }else if ("goldPassword".equals(field.getName())){
                map.put("key","银行密码");
            }else if ("wxOpenId".equals(field.getName())){
                map.put("key","微信");
            }else if ("wxNumber".equals(field.getName())){
                map.put("key","微信号");
            }else if ("wxName".equals(field.getName())){
                map.put("key","微信名称");
            }else if ("remark".equals(field.getName())){
                map.put("key","备注");
            }else if ("addTime".equals(field.getName())) {
                map.put("key", "注册时间");
                map.put("value",DateUtil.format(user.getAddTime(), "yyyy-MM-dd HH:mm:ss"));
                list.add(map);
                continue;
            }else {
                continue;
            }
            map.put("name",field.getName());
            String upName = StringUtils.captureName(field.getName());
            Method getmethod = User.class.getMethod("get" + upName);
            map.put("value", Optional.ofNullable(getmethod.invoke(user)).orElse("")+"");
            list.add(map);
        }

        HashMap<String, String> map = new HashMap<>();
        map.put("key",  "vip等级");
        map.put("name",  "vipLevel");
        map.put("value", profile.getVipLevel() + "");
        list.add(map);

        return PageResponse.builder().data(list).build();

    }

    public PageResponse goldinfo(long userId) throws Exception{

        GoldInfoVo goldInfo = profileMapper.getGoldInfo(userId);
        Field[] fields = GoldInfoVo.class.getDeclaredFields();

        //返回数组
        ArrayList<HashMap<String, String>> list = new ArrayList<>();


        for (Field field : fields) {
            HashMap<String, String> map = new HashMap<String, String>();
            if ("id".equals(field.getName())){
                map.put("key","id");
            }else if ("gold".equals(field.getName())){
                map.put("key","背包");
            }else if ("tra".equals(field.getName())){
                map.put("key","邮箱");
            } else if ("award".equals(field.getName())){
                map.put("key","返奖率");
            }else {
                continue;
            }

            String upName = StringUtils.captureName(field.getName());
            Method getmethod = GoldInfoVo.class.getMethod("get" + upName);
            map.put("value", Optional.ofNullable(getmethod.invoke(goldInfo)).orElse("")+"");
            list.add(map);
        }


        return PageResponse.builder().data(list).build();
    }


    public PageResponse up(Long id,PageRequest p) {
        if (NumberUtil.isLtOne(id)||StringUtils.isEmpty(p.getKey())||StringUtils.isEmpty(p.getValue())){
            return new PageResponse(false);
        }
        p.setValue(p.getValue().replace(" ",""));
        if ("password".equals(p.getKey())||"goldPassword".equals(p.getKey())){
            p.setValue(MD5Encrypt.MD5(p.getValue()));
        }

        //id 唯一
        User user = null;
        if ("gid".equals(p.getKey())||"telNumber".equals(p.getKey())||"accountNumber".equals(p.getKey())){
            user = userMapper.selectOne(new QueryWrapper<User>().eq(StringUtils.b2s(p.getKey()), p.getValue()));
        }
        if (null!=user){
            return new PageResponse("数据重复");
        }
        //修改前
        User oldUser = userMapper.selectById(id);
        if (!p.getKey().equals("vipLevel")){

            //db
            userMapper.upUser(id,StringUtils.b2s(p.getKey()),p.getValue());

            //redis
            User redisuser = userProfileRedisService.getRedisUserById(id);
            if (null!=redisuser){
                user = userMapper.selectById(id);
                if (null!=user){
                    redisTemplate.opsForHash().put(RedisConstantValue.USER_INFO, user.getId(), user);
                }
            }

            Object invoke = null;
            try {
                invoke = User.class.getMethod("get" + StringUtils.captureName(p.getKey())).invoke(oldUser);
            } catch (Exception e) {
                e.printStackTrace();
            }
            logService.insertLog(3,"操作用户id："+oldUser.getGid()+" 标识："+id+" 修改 "+p.getKey()+" 从 "+invoke+" 改为 "+p.getValue(),id);

        }else {
            Profile profile = profileService.getRedisProfileById(id);
            Integer vipLevel = profile.getVipLevel();

            Profile newP = new Profile();
            newP.setUserId(id);
            newP.setVipLevel(Integer.parseInt(p.getValue()));
            profileMapper.updateById(newP);
            logService.insertLog(3,"操作用户id："+oldUser.getGid()+" 标识："+id+" 修改 "+p.getKey()+" 从 "+vipLevel+" 改为 "+p.getValue(),id);

        }
        return new PageResponse();
    }

    public PageResponse allban(Long[] ids, Integer state) {
        if (null==ids||null==state||ids.length<1){
            return new PageResponse("未选中有效用户");
        }
        String thing = "";
        if (state==1){
            thing = "启用用户：";
        }else {
            thing = "禁用用户：";
        }

        User newU = new User();
        newU.setState(state);
        userMapper.banUsers(ids,state);
        List<User> users = userMapper.selectBatchIds(Arrays.stream(ids).collect(Collectors.toList()));
        for (User u : users) {
//            if (state==0){
//                registerFeignService.forceOffLine(u.getId());
//            }
            thing += u.getGid()+" ";
        }

        logService.insertLog(1,thing,0l);

        PageResponse pageResponse = new PageResponse();
        return pageResponse;
    }

    public List<List> fingip(String ip) {
        List<User> users = userMapper.selectList(new LambdaQueryWrapper<User>().eq(User::getAddIp, ip));
        ArrayList<List> res = new ArrayList<>();
        res.add(users);
        return res;
    }

    public PageResponse getRetainedData() {
        List<UserDataVo> userDataVos = userMapper.dataCount();
        return new PageResponse(userDataVos);
    }


}
